package jhunter.rt.conf.ext;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.beanutils.BeanUtils;

import jhunter.common.exception.ConfigException;
import jhunter.conf.entities.vo.Entity;
import jhunter.conf.forms.vo.EasyForm;
import jhunter.conf.module.vo.MenuItem;
import jhunter.conf.module.vo.Module;
import jhunter.rt.conf.ConfType;
import jhunter.rt.conf.Node;
import jhunter.rt.conf.Reloadable;
import jhunter.rt.conf.menu.MenuItemBean;
import jhunter.service.ModuleService;

/**
 * 中文
 * 
 * @author jkyang
 * 
 */
public class ModuleExt implements Reloadable {

	private Module module;

	private Node moduleNode;

	private static Map<ModuleExt, Map<String, ModuleService>> moduleServiceMap = new ConcurrentHashMap<ModuleExt, Map<String, ModuleService>>();

	public ModuleExt(Module module, Node moduleNode) {
		super();
		this.module = module;
		this.moduleNode = moduleNode;
	}

	public List<MenuItemBean> getMenuItem() {
		List<MenuItemBean> list = new ArrayList<MenuItemBean>();
		if (this.module.getMenu() != null) {
			List<MenuItem> items = this.module.getMenu().getMenuItem();
			for (MenuItem menuItem : items) {
				MenuItemBean bean = new MenuItemBean();
				try {
					BeanUtils.copyProperties(bean, menuItem);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
				ActionExt action = getActionByName(menuItem.getAction());
				if(action == null) {
					throw new ConfigException("action name :" + menuItem.getAction() + " not exists.");
				}
				bean.setUrl(action.getActionNode().getPathInfo().getPath());
				list.add(bean);
			}
		}
		return list;
	}

	public ActionExt getActionByName(String actionName) {
		return getActionsExt().getAction(actionName);
	}

	public ActionsExt getActionsExt() {
		for (Node node : moduleNode.getChildren()) {
			if (node.getConfType().equals(ConfType.ACTIONS)) {
				ActionsExt ser = (ActionsExt) node.getObject();
				return ser;
			}
		}
		return null;
	}

	public EasyForm getFormByName(String name) {
		List<EasyForm> forms = getFormsExt().getForms().getEasyForm();
		for (EasyForm easyForm : forms) {
			if (easyForm.getName().equals(name)) {
				return easyForm;
			}
		}
		return null;
	}

	public FormsExt getFormsExt() {
		for (Node node : moduleNode.getChildren()) {
			if (node.getConfType().equals(ConfType.FORMS)) {
				FormsExt ser = (FormsExt) node.getObject();
				return ser;
			}
		}
		return null;
	}

	public List<String> getEntityIds() {
		EntitiesExt entitiesExt = getEntitiesExt();
		if (entitiesExt != null) {
			return entitiesExt.getEntityids();
		}
		return null;
	}

	public List<Entity> getEntities() {
		return getEntitiesExt().getEntities().getEntity();
	}

	public EntitiesExt getEntitiesExt() {
		for (Node node : moduleNode.getChildren()) {
			if (node.getConfType().equals(ConfType.ENTITYS)) {
				EntitiesExt ser = (EntitiesExt) node.getObject();
				return ser;
			}
		}
		return null;
	}

	public ServicesExt getServiceExt() {
		for (Node node : moduleNode.getChildren()) {
			if (node.getConfType().equals(ConfType.SERVICES)) {
				ServicesExt ser = (ServicesExt) node.getObject();
				return ser;
			}
		}
		return null;
	}

	public Map<String, ModuleService> getModuleServiceMap() {
		if (moduleServiceMap.get(this) == null) {
			synchronized (this) {
				Map<String, ModuleService> service = getServiceExt().loadGroovyService();
				moduleServiceMap.put(this, service);
			}
		}
		return moduleServiceMap.get(this);
	}

	public Module getModule() {
		return module;
	}

	public void setModule(Module module) {
		this.module = module;
	}

	public Node getModuleNode() {
		return moduleNode;
	}

	public void setModuleNode(Node moduleNode) {
		this.moduleNode = moduleNode;
	}

	public void unloadService() {
		moduleServiceMap.remove(this);
	}

	@Override
	public void unload() {
		unloadService();
	}

	@Override
	public void afterLoad() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init() {
		afterLoad();
	}

}
